/**
 * 数据同步服务
 * 用于确保应用中各模块数据的一致性，如血糖记录更新后自动更新健康分数等
 */
// 不使用pinia，避免组件外部直接调用出错
// import { useBloodSugarStore } from '@/store/pinia.js'
import { getCurrentDate } from '@/common/utils/date.js'
import mockData from '../mock/index.js'
import { getRecords } from '../api/record.js'
import { getDietRecords } from '../api/diet.js'
import { getReminders } from '../api/reminder.js'

// 缓存系统
const dataCache = {
  // 缓存数据
  cache: {},
  
  // 缓存有效期(毫秒)
  maxAge: 60 * 1000, // 默认1分钟
  
  // 获取缓存数据
  get(key) {
    const data = this.cache[key]
    if (!data) return null
    
    // 检查缓存是否过期
    if (Date.now() - data.timestamp > this.maxAge) {
      delete this.cache[key]
      return null
    }
    
    return data.value
  },
  
  // 设置缓存
  set(key, value, customMaxAge) {
    this.cache[key] = {
      value,
      timestamp: Date.now(),
      maxAge: customMaxAge || this.maxAge
    }
  },
  
  // 清除缓存
  clear(key) {
    if (key) {
      delete this.cache[key]
    } else {
      this.cache = {}
    }
  }
}

/**
 * 同步血糖数据服务
 * 负责在血糖记录变更时更新相关数据和统计信息
 */
const bloodSugarSyncService = {
  /**
   * 同步健康评分
   * 根据血糖数据的变化更新用户健康评分
   * @param {Array} records 血糖记录
   */
  syncHealthScore(records) {
    try {
      // 不再直接使用pinia store，而是使用传入的血糖记录或从本地存储获取
      const bloodSugarRecords = records || uni.getStorageSync('bloodSugarRecords') || []
      
      // 获取最近一周的记录
      const now = new Date()
      const oneWeekAgo = new Date()
      oneWeekAgo.setDate(oneWeekAgo.getDate() - 7)
      
      const recentRecords = bloodSugarRecords.filter(record => {
        const recordDate = new Date(record.date)
        return recordDate >= oneWeekAgo && recordDate <= now
      })
      
      // 如果没有足够的记录，则不更新分数
      if (recentRecords.length < 3) return
      
      // 根据血糖异常情况计算扣分
      let abnormalCount = 0
      let severityScore = 0
      
      recentRecords.forEach(record => {
        const value = parseFloat(record.value)
        
        // 根据不同类型的血糖记录判断正常范围
        let isNormal = true
        let severityFactor = 0
        
        // 空腹血糖标准
        if (['beforeBreakfast', 'beforeLunch', 'beforeDinner'].includes(record.type)) {
          if (value < 3.9) {
            isNormal = false
            severityFactor = (3.9 - value) * 5  // 低血糖严重程度
          } else if (value > 6.1) {
            isNormal = false
            severityFactor = (value - 6.1) * 3  // 高血糖严重程度
          }
        } 
        // 餐后血糖标准
        else if (['afterBreakfast', 'afterLunch', 'afterDinner'].includes(record.type)) {
          if (value < 3.9) {
            isNormal = false
            severityFactor = (3.9 - value) * 5
          } else if (value > 7.8) {
            isNormal = false
            severityFactor = (value - 7.8) * 3
          }
        }
        // 睡前血糖标准
        else if (record.type === 'beforeSleep') {
          if (value < 3.9) {
            isNormal = false
            severityFactor = (3.9 - value) * 5
          } else if (value > 6.7) {
            isNormal = false
            severityFactor = (value - 6.7) * 3
          }
        }
        
        if (!isNormal) {
          abnormalCount++
          severityScore += severityFactor
        }
      })
      
      // 计算新的健康分数
      const abnormalRate = abnormalCount / recentRecords.length
      const baseScore = 100
      
      // 异常率扣分
      const abnormalDeduction = Math.round(abnormalRate * 20)
      
      // 严重程度扣分
      const severityDeduction = Math.min(10, Math.round(severityScore))
      
      // 测量规律性加分 (每天至少一次得满分5分)
      const daysWithRecords = new Set(recentRecords.map(r => r.date)).size
      const regularityBonus = Math.round((daysWithRecords / 7) * 5)
      
      // 计算最终分数
      let healthScore = baseScore - abnormalDeduction - severityDeduction + regularityBonus
      healthScore = Math.max(60, Math.min(100, healthScore))  // 限制在60-100之间
      
      // 存储到本地
      const userInfo = uni.getStorageSync('userInfo') || {}
      userInfo.healthScore = healthScore
      uni.setStorageSync('userInfo', userInfo)
      
      console.log('健康分数已更新:', healthScore)
      
      return healthScore
    } catch (error) {
      console.error('同步健康分数失败:', error)
      return null
    }
  },
  
  /**
   * 同步血糖统计数据
   * @param {Array} records 血糖记录
   */
  syncStatistics(records) {
    // 这里可以实现更新血糖统计数据的逻辑
    // 实际项目中可能会调用API将数据同步到服务器，然后由服务器计算统计数据
    // 在本项目中使用的是Mock数据，暂不实现具体逻辑
  }
}

// 主数据同步服务
const dataSyncService = {
  /**
   * 同步血糖相关数据
   * 当血糖记录发生变化时调用此方法，更新相关联的数据
   * @param {Array} records 血糖记录数组
   * @param {String} action 操作类型: add, update, delete
   */
  syncBloodSugarData(records, action = 'update') {
    // 清除相关缓存
    dataCache.clear('bloodSugar.statistics')
    dataCache.clear('bloodSugar.recentRecords')
    
    // 同步健康分数
    const healthScore = bloodSugarSyncService.syncHealthScore(records)
    
    // 同步统计数据
    bloodSugarSyncService.syncStatistics(records)
    
    // 发布事件通知其他模块
    uni.$emit('bloodSugar:dataChanged', {
      action,
      healthScore
    })
    
    return {
      success: true,
      healthScore
    }
  },
  
  /**
   * 保存血糖记录到本地存储
   * @param {Array} records 血糖记录数组
   */
  persistBloodSugarRecords(records) {
    uni.setStorageSync('bloodSugarRecords', records || [])
  },
  
  /**
   * 从本地存储加载血糖记录
   * @returns {Array} 血糖记录数组
   */
  loadBloodSugarRecords() {
    return uni.getStorageSync('bloodSugarRecords') || []
  },
  
  /**
   * 数据一致性检查
   * 检查本地存储的数据是否一致，如果不一致则进行修复
   */
  checkDataConsistency() {
    try {
      // 尝试从API获取最新数据并更新本地存储
      if (!mockData.useMock) {
        // 如果不是使用模拟数据，才尝试从API获取
        try {
          // 异步获取血糖记录
          getRecords().then(res => {
            if (res && res.code === 0 && res.data) {
              // 更新本地存储
              uni.setStorageSync('bloodSugarRecords', res.data)
              console.log('已从API更新血糖记录数据，条数:', res.data.length)
              
              // 同步更新相关数据
              this.syncBloodSugarData(res.data)
            }
          }).catch(err => {
            console.error('从API获取血糖记录失败:', err)
          })
          
          // 异步获取饮食记录
          getDietRecords().then(res => {
            if (res && res.code === 0 && res.data) {
              uni.setStorageSync('dietRecords', res.data)
              console.log('已从API更新饮食记录数据')
            }
          }).catch(err => {
            console.error('从API获取饮食记录失败:', err)
          })
          
          // 异步获取提醒记录
          getReminders().then(res => {
            if (res && res.code === 0 && res.data) {
              uni.setStorageSync('reminders', res.data)
              console.log('已从API更新提醒数据')
            }
          }).catch(err => {
            console.error('从API获取提醒记录失败:', err)
          })
        } catch (apiError) {
          console.error('API数据同步失败:', apiError)
        }
      }
      
      // 继续使用本地数据进行一致性检查
      const records = this.loadBloodSugarRecords()
      
      // 检查记录是否过期 (超过90天的记录可以考虑归档)
      const now = new Date()
      const ninetyDaysAgo = new Date()
      ninetyDaysAgo.setDate(ninetyDaysAgo.getDate() - 90)
      
      const hasExpiredRecords = records.some(record => {
        const recordDate = new Date(record.date)
        return recordDate < ninetyDaysAgo
      })
      
      if (hasExpiredRecords) {
        console.log('检测到过期记录，可以考虑进行归档')
        // 这里可以实现归档逻辑
      }
      
      // 同步数据，使用传入的records参数
      this.syncBloodSugarData(records)
      
      return {
        success: true,
        message: '数据一致性检查完成'
      }
    } catch (error) {
      console.error('数据一致性检查失败:', error)
      return {
        success: false,
        message: '数据一致性检查失败: ' + error.message
      }
    }
  },
  
  /**
   * 添加血糖记录（服务器成功同步后）
   * @param {Object} record - 血糖记录
   */
  addRecord(record) {
    try {
      // 更新本地存储
      const records = uni.getStorageSync('bloodSugarRecords') || []
      records.unshift(record)
      uni.setStorageSync('bloodSugarRecords', records)
      
      // 发送数据更新通知
      uni.$emit('bloodSugar:dataChanged', {
        action: 'add',
        record
      })
      
      console.log('记录已添加到本地存储')
    } catch (e) {
      console.error('添加记录到本地存储失败:', e)
    }
  },
  
  /**
   * 添加本地血糖记录（服务器同步失败时使用）
   * @param {Object} record - 血糖记录
   */
  addLocalRecord(record) {
    try {
      // 确保记录有isLocal标记
      record.isLocal = true
      record.createTime = record.createTime || new Date().toISOString()
      
      // 1. 添加到本地记录集合
      const localRecords = uni.getStorageSync('localBloodSugarRecords') || []
      localRecords.unshift(record)
      uni.setStorageSync('localBloodSugarRecords', localRecords)
      
      // 2. 同时添加到主记录列表，以便在UI中显示
      const records = uni.getStorageSync('bloodSugarRecords') || []
      records.unshift({...record, synced: false})
      uni.setStorageSync('bloodSugarRecords', records)
      
      // 3. 发送数据变更通知
      uni.$emit('bloodSugar:dataChanged', {
        action: 'add',
        record: {...record, synced: false}
      })
      
      console.log('记录已添加到本地临时存储')
      
      // 4. 将待同步记录添加到同步队列
      this.addToSyncQueue(record)
    } catch (e) {
      console.error('添加本地记录失败:', e)
    }
  },
  
  /**
   * 添加记录到同步队列
   * @param {Object} record - 要同步的记录
   */
  addToSyncQueue(record) {
    try {
      const syncQueue = uni.getStorageSync('syncQueue') || []
      syncQueue.push({
        type: 'bloodSugar',
        action: 'add',
        data: record,
        timestamp: new Date().getTime()
      })
      uni.setStorageSync('syncQueue', syncQueue)
      console.log('记录已添加到同步队列')
    } catch (e) {
      console.error('添加到同步队列失败:', e)
    }
  },
  
  /**
   * 尝试同步本地记录到服务器
   * @returns {Promise}
   */
  syncLocalRecords: async () => {
    try {
      const syncQueue = uni.getStorageSync('syncQueue') || []
      if (syncQueue.length === 0) {
        console.log('没有需要同步的记录')
        return Promise.resolve({success: true, message: '没有需要同步的记录'})
      }
      
      console.log(`开始同步${syncQueue.length}条本地记录...`)
      
      // 过滤出血糖记录
      const bloodSugarTasks = syncQueue.filter(item => item.type === 'bloodSugar' && item.action === 'add')
      
      if (bloodSugarTasks.length === 0) {
        return Promise.resolve({success: true, message: '没有需要同步的血糖记录'})
      }
      
      // 创建同步任务
      const syncTasks = bloodSugarTasks.map(task => {
        // 转换为后端格式
        const backendRecord = dataSyncService.convertToBackendFormat(task.data)
        
        // 调用API
        return dataSyncService.saveBloodSugarRecord(backendRecord)
          .then(res => {
            console.log('同步成功:', res)
            return {
              taskId: task.timestamp,
              success: true,
              data: res
            }
          })
          .catch(err => {
            console.error('同步失败:', err)
            return {
              taskId: task.timestamp,
              success: false,
              error: err
            }
          })
      })
      
      // 执行所有同步任务
      const results = await Promise.all(syncTasks)
      
      // 处理结果
      const successTasks = results.filter(r => r.success).map(r => r.taskId)
      
      if (successTasks.length > 0) {
        // 从队列中移除成功的任务
        const newQueue = syncQueue.filter(task => !successTasks.includes(task.timestamp))
        uni.setStorageSync('syncQueue', newQueue)
        
        // 从本地记录中移除已同步的记录
        dataSyncService.removeLocalRecords(successTasks)
        
        // 刷新血糖记录列表
        dataSyncService.refreshBloodSugarRecords()
      }
      
      return {
        success: true,
        total: bloodSugarTasks.length,
        success: successTasks.length,
        failed: bloodSugarTasks.length - successTasks.length
      }
    } catch (e) {
      console.error('同步本地记录失败:', e)
      return Promise.reject(e)
    }
  },
  
  /**
   * 从本地记录中移除已同步的记录
   * @param {Array} taskIds - 已成功同步的任务ID
   */
  removeLocalRecords(taskIds) {
    try {
      const localRecords = uni.getStorageSync('localBloodSugarRecords') || []
      const newLocalRecords = localRecords.filter(record => {
        // 查找对应的时间戳，通常是记录的创建时间或ID
        const timestamp = record.createTime ? new Date(record.createTime).getTime() : record.id
        return !taskIds.includes(timestamp)
      })
      
      uni.setStorageSync('localBloodSugarRecords', newLocalRecords)
      console.log(`已从本地记录中移除${localRecords.length - newLocalRecords.length}条已同步记录`)
    } catch (e) {
      console.error('移除已同步记录失败:', e)
    }
  },
  
  /**
   * 检查数据一致性
   */
  checkDataConsistency() {
    try {
      const syncQueue = uni.getStorageSync('syncQueue') || []
      if (syncQueue.length > 0) {
        console.log(`检测到${syncQueue.length}条未同步的记录，尝试同步...`)
        dataSyncService.syncLocalRecords().then(res => {
          console.log('自动同步结果:', res)
        }).catch(e => {
          console.error('自动同步失败:', e)
        })
      }
    } catch (e) {
      console.error('检查数据一致性失败:', e)
    }
  },
  
  /**
   * 刷新血糖记录列表
   */
  refreshBloodSugarRecords: async () => {
    try {
      const result = await dataSyncService.getBloodSugarRecords()
      if (result.code === 0) {
        uni.setStorageSync('bloodSugarRecords', result.data)
        
        // 发送刷新通知
        uni.$emit('bloodSugar:dataRefreshed', {
          action: 'refresh',
          data: result.data
        })
        
        console.log('血糖记录已刷新')
        return true
      }
      return false
    } catch (e) {
      console.error('刷新血糖记录失败:', e)
      return false
    }
  },
  
  /**
   * 将前端记录格式转换为后端所需格式
   * @param {Object} frontendRecord - 前端记录
   * @returns {Object} - 后端格式记录
   */
  convertToBackendFormat(frontendRecord) {
    // 将type转换为measureType的数值
    const measureTypeMap = {
      'beforeBreakfast': 1, // 空腹
      'afterBreakfast': 3, // 餐后1小时
      'beforeLunch': 2, // 餐前
      'afterLunch': 3, // 餐后1小时
      'beforeDinner': 2, // 餐前
      'afterDinner': 3, // 餐后1小时
      'beforeSleep': 5, // 睡前
      'random': 7 // 随机
    }
    
    // 合并日期和时间
    const dateTime = `${frontendRecord.date}T${frontendRecord.time}:00`;
    
    // 构建符合后端数据库字段结构的数据
    // 严格按照数据库表结构，不包含unit和meal字段
    return {
      userId: frontendRecord.userId || 1, // 用户ID
      value: parseFloat(frontendRecord.value), // 血糖值
      measureTime: dateTime, // 测量时间
      measureType: measureTypeMap[frontendRecord.type] || 1, // 测量类型
      remark: frontendRecord.remark || '' // 备注
    }
  },
  
  /**
   * 调用API保存血糖记录
   * @param {Object} record - 血糖记录
   * @returns {Promise}
   */
  saveBloodSugarRecord(record) {
    // 这里需要实现调用API保存血糖记录的逻辑
    // 由于涉及到API调用，这里需要返回一个Promise
    return new Promise((resolve, reject) => {
      // 模拟API调用
      setTimeout(() => {
        // 假设API调用成功
        resolve({code: 0, data: record})
      }, 1000) // 模拟网络延迟
    })
  },
  
  /**
   * 调用API获取血糖记录
   * @returns {Promise}
   */
  getBloodSugarRecords() {
    // 这里需要实现调用API获取血糖记录的逻辑
    // 由于涉及到API调用，这里需要返回一个Promise
    return new Promise((resolve, reject) => {
      // 模拟API调用
      setTimeout(() => {
        // 假设API调用成功
        resolve({code: 0, data: dataSyncService.loadBloodSugarRecords()})
      }, 1000) // 模拟网络延迟
    })
  }
}

export default dataSyncService 